# -*- coding: utf-8 -*-

import socket,json,serial,thread,threading,struct,time
from math import *

def blh2ecef(lat,lon,hei):
    Lambda=lon*pi/180.0
    Theta=lat*pi/180.0
    h=hei
    RE_WGS84=6378137.0           #earth semimajor axis (WGS84) (m) =a 长半径
    FE_WGS84=(1.0/298.257223563) #earth flattening (WGS84) =(a-b)/a
    e2=FE_WGS84*(2.0-FE_WGS84)
    N=RE_WGS84/sqrt(1.0-e2*sin(Theta)**2)
    return ((N+h)*cos(Theta)*cos(Lambda), (N+h)*cos(Theta)*sin(Lambda), (N*(1-e2)+h)*sin(Theta))

def nmea2json(nmea):
    if nmea.startswith('$GPGGA'):
        #print '+'
        global BLH
        BLH=[0,0,0]
        try:
            BLH[0]=nmea.split(',')[2]
            BLH[0]=int(BLH[0][:2])+float(BLH[0][2:])/60
            BLH[1]=nmea.split(',')[4]
            BLH[1]=int(BLH[1][:3])+float(BLH[1][3:])/60
            BLH[2]=float(nmea.split(',')[9])
        except:
            pass
    if nmea.startswith('$GPGSA'):
        #print '-'
        global SatNum
        SatNum=[]
        try:
            SatNum=nmea.split(',')[3:-3]
            SatNum=[int(s) for s in SatNum if s]
            if BLH:
                #print '='
                x,y,z=blh2ecef(BLH[0],BLH[1],BLH[2])
                Json={'num':len(SatNum), 'x':x, 'y':y, 'z':z, 'PRN':SatNum}
                return json.dumps(Json)
        except e:
            print e
    return False

def nmea2server(lock,nmea,conn):
    #print nmea
    Json=nmea2json(nmea)
    global f
    if Json:
        lock.acquire()
        print time.ctime()+'\n'+Json
        conn.send(struct.pack('!I',len(Json)))
        conn.send(Json)
        rcv=conn.recv(100);rcv=rcv[:rcv.find('}')+1]
        print rcv,'\n--------------------------\n'
        f.write(time.ctime()+'\n'+str(Json)+'\n'+rcv+'\n--------------------------\n')
        lock.release()
    thread.exit_thread()

def main(com,baud,ip,port):
    ser=serial.Serial(com,baud)
    mylock = threading.RLock()
    conn=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    conn.connect((ip,port))
    while True:
        nmea=ser.readline()
        thread.start_new_thread(nmea2server, (mylock,nmea,conn))  
    conn.close()
    ser.close()

if __name__=='__main__':
    com=raw_input("com: ")
    baud=int(raw_input("baud rate: "))
    ip=raw_input("ip: ")
    port=i